﻿#include <vf_pch.h>
#include <vf_StorageUtils.h>
#include <vf_apiutils.h>
#include <vf_sink.h>
#include <VFAdapterAPIs.h>
#include <vf_tcpclient.h>
#include <vf_tcpserver.h>



namespace VFAdapter
{
    //using DVec3d = Eigen::Vector<double, 3>;
    //using DPoint3d = Eigen::Vector<double, 3>;
    //namespace fw = SolidEdgeFramework;
    //namespace pt = SolidEdgePart;
    // namespace cs = SolidEdgeConstants;
    // namespace gm = SolidEdgeGeometry;
    // namespace fwp = SolidEdgeFrameworkSupport;
    // fw::ApplicationPtr SEAPP = nullptr;

    // 定义数据结构体（用于序列化）
#pragma pack(push, 1)  // 确保结构体内存对齐
    struct ArrowMappingData {
        int64_t ptID;
        int64_t normalLid;
        int64_t normalLid1;
        int64_t normalLid2;
    };
#pragma pack(pop)

    //------------------------------------------
    // 保存映射关系到复合文档
    //------------------------------------------
    void SaveMapping(int64_t ptID, int64_t normalLid, int64_t normalLid1, int64_t normalLid2)
    {
        // 获取当前活动文档
        pt::PartDocumentPtr pPartDoc = SEAPP->GetActiveDocument();
        if (!pPartDoc) {
            MessageBox(NULL, L"无法获取活动文档", L"错误", MB_ICONERROR);
            return;
        }

        // 打开或创建存储对象
        IStoragePtr pRootStg = nullptr;
        pRootStg = pPartDoc->GetAddInsStorage(
        OLESTR("ArrowMappings"),
        STGM_DIRECT | STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE);

        assert(pRootStg != nullptr);
        HRESULT hr = S_OK;

        // 创建流对象
        IStreamPtr pStream = nullptr;
        hr = pRootStg->CreateStream(
            OLESTR("MappingData"),
            STGM_DIRECT | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE,
            0, 0, &pStream
        );
        if (FAILED(hr) || !pStream) {
            _com_error err(hr);
            MessageBox(NULL, err.ErrorMessage(), L"锟斤拷锟斤拷锟斤拷失锟斤拷", MB_ICONERROR);
            return;
        }

        // 填充数据结构
        ArrowMappingData data;
        data.ptID = ptID;
        data.normalLid = normalLid;
        data.normalLid1 = normalLid1;
        data.normalLid2 = normalLid2;

        // 写入数据到流
        ULONG bytesWritten = 0;
        hr = pStream->Write(&data, sizeof(ArrowMappingData), &bytesWritten);
        if (FAILED(hr))
        {
            _com_error err(hr);
            MessageBox(NULL, err.ErrorMessage(), L"写锟斤拷失锟斤拷", MB_ICONERROR);
            return;
        }

        // 提交更改
        hr = pStream->Commit(STGC_DEFAULT | STGC_OVERWRITE);
        hr = pRootStg->Commit(STGC_DEFAULT | STGC_OVERWRITE);

        // 保存到持久化存储
        IPersistStoragePtr pPersistStorage = pPartDoc;
        hr = pPersistStorage->Save(pRootStg, FALSE);
    }

    //------------------------------------------
    // 从复合文档加载映射关系
    //------------------------------------------
    bool LoadMapping(int64_t& outPtID, int64_t& outNormalLid,
        int64_t& outNormalLid1, int64_t& outNormalLid2)
    {
        // 获取当前活动文档
        pt::PartDocumentPtr pPartDoc = SEAPP->GetActiveDocument();
        if (!pPartDoc) {
            MessageBox(NULL, L"锟睫凤拷锟斤拷取锟筋动锟侥碉拷", L"锟斤拷锟斤拷", MB_ICONERROR);
            return false;
        }

        // 打开存储对象
        IStoragePtr pRootStg = nullptr;
        pRootStg = pPartDoc->GetAddInsStorage(
            OLESTR("ArrowMappings"),
            STGM_DIRECT | STGM_READ | STGM_SHARE_EXCLUSIVE);

        assert(pRootStg != nullptr);
        HRESULT hr = S_OK;

        // 打开流对象
        IStreamPtr pStream = nullptr;
        hr = pRootStg->OpenStream(
            OLESTR("MappingData"),
            NULL,
            STGM_READ | STGM_SHARE_EXCLUSIVE,
            0,
            &pStream
        );

        assert(pStream != nullptr);

        // 读取数据
        ArrowMappingData data;
        ULONG bytesRead = 0;
        hr = pStream->Read(&data, sizeof(ArrowMappingData), &bytesRead);
        if (FAILED(hr) || bytesRead != sizeof(ArrowMappingData)) {
            MessageBox(NULL, L"数据读取不完整", L"错误", MB_ICONERROR);
            return false;
        }

        // 返回读取的值
        outPtID = data.ptID;
        outNormalLid = data.normalLid;
        outNormalLid1 = data.normalLid1;
        outNormalLid2 = data.normalLid2;

        return true;
    }


     bool LoadAsBytesFromFile(const wchar_t* filePath, OUT std::vector<BYTE>& vctBytes) {
        HANDLE hFile = CreateFileW(
            filePath,               // 宽字符路径
            GENERIC_READ,           // 只读访问
            FILE_SHARE_READ,        // 共享读取
            NULL,                   // 安全属性
            OPEN_EXISTING,          // 打开已存在文件
            FILE_ATTRIBUTE_NORMAL,  // 正常文件属性
            NULL
        );

        if (hFile == INVALID_HANDLE_VALUE) {
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__;
            return false;
        }

        // 获取文件大小
        LARGE_INTEGER fileSize;
        if (!GetFileSizeEx(hFile, &fileSize)) {
            CloseHandle(hFile);
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__;
            return false;
        }

        // 确保文件大小在可处理范围内
        if (fileSize.QuadPart > MAXDWORD) {
            CloseHandle(hFile);
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__;
            return false;
        }

        DWORD bufferSize = static_cast<DWORD>(fileSize.QuadPart);
        vctBytes.clear();
        vctBytes.resize(bufferSize);



        /*{
            unsigned char* buffer = new unsigned char[bufferSize];
            DWORD bytesRead;

            if (ReadFile(hFile, buffer, sizeof(unsigned char) * bufferSize, &bytesRead, NULL)) {
                printf("读取了 %d 字节: %.*s\n", bytesRead, bytesRead, buffer);
            }
            delete[] buffer;
        }*/
        DWORD bytesRead = 0;
        if (!ReadFile(hFile, vctBytes.data(), bufferSize, &bytesRead, NULL)) {
            CloseHandle(hFile);
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__;
            return false;
        }

        CloseHandle(hFile);

        if (bytesRead != bufferSize) {
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__;
            return false;
        }

        return true;
    }

     bool OverwriteFileFromBytes(const wchar_t* filePath, std::vector<BYTE>& vctBytes)
     {    
         // 将宽字符路径转换为 filesystem::path
         std::filesystem::path path(filePath);

         // 打开文件：binary + trunc 模式
         std::ofstream file(path, std::ios::binary | std::ios::trunc);

         if (!file.is_open()) {
            BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__; \
            return false;
         }

         // 写入二进制数据
         file.write(reinterpret_cast<const char*>(vctBytes.data()),
             static_cast<std::streamsize>(vctBytes.size()));

         if (!file.good()) {
             BOOST_LOG_TRIVIAL(error) << __func__ << " ,  " << __LINE__; \
                 return false;
         }
         return true;
     }


    //------------------------------------------
    // 使用示例
    //------------------------------------------
    void ExampleUsage()
    {
        ////保存示例
        //int64_t ptID = std::stoull("123456789");
        //int64_t normalLid = ApiUtils::GetObjectID(pline3D);
        //int64_t normalLid1 = ApiUtils::GetObjectID(pline3D);
        //int64_t normalLid2 = ApiUtils::GetObjectID(pline3D);
        //SaveMapping(ptID, normalLid, normalLid1, normalLid2);

        //// // 加载示例
        //int64_t loadedPtID, loadedLid, loadedLid1, loadedLid2;
        //if (LoadMapping(loadedPtID, loadedLid, loadedLid1, loadedLid2)) {
        //    // 使用加载的数据...
        //}
    }

}